package cs383.GradUnit;
/* Card Images Taken From http://www.jfitz.com/cards/ */

/**
 *  GUI Explanation
 *  
 *  Player Indicator Label
 *  	When dealer button is moved the indicator label is updated to whether they are in hand, out of game, or yet to act
 *  	When player makes a decision the indicator is updated to what their last action was
 *  	At the start of each betting round the indicators are updated to match the status of in hand, out of game, or yet to act
 */
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AbsoluteLayout;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;



public class aGame extends Activity {
	
	private static final int dealerButtonWidth = 20;
	private static final int dealerButtonHeight = 20;
	private static final int STARTINGCHIPS = 1000;
	private static final int MIN_BET = 0;
	private static final int HUMAN_PLAYER = 0;
	//private static final int FOLD = 0;
	//private static final int CALL = 2;
	//private static final int ALL_IN = 3;
	private static final String CURRENTPOT = "Current Pot: "; 
	private static final String CURRENTROUND = "Current Hand: ";
	private static final String CURRENTBET = "Current Bet: ";
	private static final String CHIPS = "";
	private static final int TIME_DELAY = 4000;
	private static final int TIME_AFTER_BETTING_ROUND = 4000;
	private boolean userJustMadeTurn = false;
	private boolean playerJustMadeTurn = false;
	
	AbsoluteLayout gameLayout, lytPlayer0,lytPlayer1,lytPlayer2,lytPlayer3;
	Button btnCall, btnCheck, btnFold, btnBet, btnAllIn;
	SeekBar sldrBettingSlider;
	OnClickListener listenerCall, listenerCheck, listenerFold, listenerBet, listenerAllIn;
	OnSeekBarChangeListener listenerBettingSlider;
	ImageView imgDealerButton, imgPlayer0Card1, imgPlayer0Card2,imgPlayer1Card1, imgPlayer1Card2;
	ImageView imgPlayer2Card1, imgPlayer2Card2,imgPlayer3Card1, imgPlayer3Card2;
	ImageView imgCommCard1, imgCommCard2, imgCommCard3, imgCommCard4, imgCommCard5;
	TextView txtCurrentPot, txtCurrentRound, txtCurrentBet, txtPlayer0Chips, txtPlayer1Chips, txtPlayer2Chips, txtPlayer3Chips, txtSliderValue;
	TextView txtPlayer0Status,txtPlayer1Status, txtPlayer2Status, txtPlayer3Status;
	ArrayList<cPoint> dealerButtonPoints;
	ArrayList<cPlayer> playerList;
	
	int sliderBet;
	private cTable pokerTable;
	Handler mHandler = new Handler();
	
	Runnable dealPlayer0Card1 = new Runnable() {
	    public void run() {
	    	if(pokerTable.checkPlayerInGame(0)){
		    	pokerTable.dealCard(0);
		    	
		    	imgPlayer0Card1.setVisibility(View.VISIBLE);
		    	imgPlayer0Card1.setImageDrawable(getCardImage(pokerTable.getPlayerCardIndex(0, 0)));
		    	imgPlayer0Card1.invalidate();
		    	
		    	Log.d("card1", "Your first card is " + pokerTable.getPlayerCardIndex(0, 0));
	    	}
	    }
	};
	Runnable dealPlayer0Card2 = new Runnable() {
	    public void run() {
	    	if(pokerTable.checkPlayerInGame(0)){
		    	pokerTable.dealCard(0);
		    	
		    	imgPlayer0Card2.setVisibility(View.VISIBLE);
		    	imgPlayer0Card2.setImageDrawable(getCardImage(pokerTable.getPlayerCardIndex(0, 1)));
		    	imgPlayer0Card2.invalidate();
		    	
		    	Log.d("card2", "Your second card is " + pokerTable.getPlayerCardIndex(0, 1));
	    	}
	    }
	};
	Runnable dealPlayer1Card1 = new Runnable() {
	    public void run() {
	    	if(pokerTable.checkPlayerInGame(1)){
		    	imgPlayer1Card1.setVisibility(View.VISIBLE);
		    	imgPlayer1Card1.setImageDrawable(getResources().getDrawable(R.drawable.cardback));
		    	imgPlayer1Card1.invalidate();
		    	
		    	pokerTable.dealCard(1);
		    	Log.d("player1Card1", "player1 card1 is " + pokerTable.getPlayerCardIndex(1, 0));
	    	}
	    }
	};
	Runnable dealPlayer1Card2 = new Runnable() {
	    public void run() {
	    	if(pokerTable.checkPlayerInGame(1)){
		    	imgPlayer1Card2.setVisibility(View.VISIBLE);
		    	imgPlayer1Card2.setImageDrawable(getResources().getDrawable(R.drawable.cardback));
		    	imgPlayer1Card2.invalidate();
		    	
		    	pokerTable.dealCard(1);
		    	Log.d("player1Card2", "player1 card2 is " + pokerTable.getPlayerCardIndex(1, 1));
	    	}
	    }
	};
	Runnable dealPlayer2Card1 = new Runnable() {
	    public void run() {
	    	if(pokerTable.checkPlayerInGame(2)){
		    	imgPlayer2Card1.setVisibility(View.VISIBLE);
		    	imgPlayer2Card1.setImageDrawable(getResources().getDrawable(R.drawable.cardback));
		    	imgPlayer2Card1.invalidate();
		    	
		    	pokerTable.dealCard(2);
		    	Log.d("player2Card1", "player2 card1 is " + pokerTable.getPlayerCardIndex(2, 0));
	    	}
	    }
	};
	Runnable dealPlayer2Card2 = new Runnable() {
	    public void run() {
	    	if(pokerTable.checkPlayerInGame(2)){
		    	imgPlayer2Card2.setVisibility(View.VISIBLE);
		    	imgPlayer2Card2.setImageDrawable(getResources().getDrawable(R.drawable.cardback));
		    	imgPlayer2Card2.invalidate();
		    	
		    	pokerTable.dealCard(2);
		    	Log.d("player2Card2", "player2 card2 is " + pokerTable.getPlayerCardIndex(2, 1));
	    	}
	    }
	};
	Runnable dealPlayer3Card1 = new Runnable() {
	    public void run() {
	    	if(pokerTable.checkPlayerInGame(3)){
		    	imgPlayer3Card1.setVisibility(View.VISIBLE);
		    	imgPlayer3Card1.setImageDrawable(getResources().getDrawable(R.drawable.cardback));
		    	imgPlayer3Card1.invalidate();
		    	
		    	pokerTable.dealCard(3);
		    	Log.d("player3Card1", "player3 card1 is " + pokerTable.getPlayerCardIndex(3, 0));
	    	}
	    }
	};
	Runnable dealPlayer3Card2 = new Runnable() {
	    public void run() {
	    	if(pokerTable.checkPlayerInGame(3)){
		    	imgPlayer3Card2.setVisibility(View.VISIBLE);
		    	imgPlayer3Card2.setImageDrawable(getResources().getDrawable(R.drawable.cardback));
		    	imgPlayer3Card2.invalidate();
		    	
		    	pokerTable.dealCard(3);
		    	Log.d("player3Card2", "player3 card2 is " + pokerTable.getPlayerCardIndex(3, 1));
	    	}
	    }
	};
	
	Runnable moveToBettingAfterDeal = new Runnable() {
	    public void run() {
	    	//resetAllPlayerStatusIndicators();
	    	roundOfBetting();
	    }
	};
	Runnable moveToBettingAfterRound = new Runnable() {
	    public void run() {
	    	//resetAllPlayerStatusIndicators();
	    	roundOfBetting();
	    }
	};
	
	Runnable dealFlop = new Runnable() {
	    public void run() {
	    	if(pokerTable.getNumberOfActivePlayers() > 1){
				flop();
	    	}
			else
				awardPot();
	    }
	};
	Runnable dealTurn = new Runnable() {
	    public void run() {
	    	if(pokerTable.getNumberOfActivePlayers() > 1){
				turn();
	    	}
			else
				awardPot();
	    }
	};
	Runnable dealRiver = new Runnable() {
	    public void run() {
	    	if(pokerTable.getNumberOfActivePlayers() > 1){
				river();
	    	}
			else
				awardPot();
	    }
	};
	
	Runnable dealFlop1 = new Runnable() {
	    public void run() {
	    	imgCommCard1.setVisibility(View.VISIBLE);
	    	imgCommCard1.setImageDrawable(getCardImage(pokerTable.getCommunityCardIndex(0)));
	    	imgCommCard1.invalidate();
	    }
	};
	Runnable dealFlop2 = new Runnable() {
	    public void run() {
	    	imgCommCard2.setVisibility(View.VISIBLE);
	    	imgCommCard2.setImageDrawable(getCardImage(pokerTable.getCommunityCardIndex(1)));
	    	imgCommCard2.invalidate();
	    }
	};
	Runnable dealFlop3 = new Runnable() {
	    public void run() {
	    	imgCommCard3.setVisibility(View.VISIBLE);
	    	imgCommCard3.setImageDrawable(getCardImage(pokerTable.getCommunityCardIndex(2)));
	    	imgCommCard3.invalidate();
	    }
	};
	Runnable dealTurn1 = new Runnable() {
	    public void run() {
	    	imgCommCard4.setVisibility(View.VISIBLE);
	    	imgCommCard4.setImageDrawable(getCardImage(pokerTable.getCommunityCardIndex(3)));
	    	imgCommCard4.invalidate();
	    }
	};
	Runnable dealRiver1 = new Runnable() {
	    public void run() {
	    	imgCommCard5.setVisibility(View.VISIBLE);
	    	imgCommCard5.setImageDrawable(getCardImage(pokerTable.getCommunityCardIndex(4)));
	    	imgCommCard5.invalidate();
	    }
	};
	Runnable updateGUIEndOfHand = new Runnable(){
		public void run(){
			updateSlider();
			updateText();
	    	clearPlayerCardImages();
	    	clearCommunityCardImages();
		}
	};
	Runnable endOfHand = new Runnable(){
		public void run(){
			if(pokerTable.getNumberOfActivePlayers() == 1 && pokerTable.checkPlayerInGame(HUMAN_PLAYER)){  //if player won
				Intent endGame = new Intent(aGame.this,aEndGame.class);
				endGame.putExtra("OUTCOME", "YOU WON!");
				startActivity(endGame);
			}
			else if(!pokerTable.checkPlayerInGame(HUMAN_PLAYER)){
				Intent endGame = new Intent(aGame.this,aEndGame.class);
				endGame.putExtra("OUTCOME", "YOU LOST");
				startActivity(endGame);
			}
			else{
				
				newHand();
			}
		}
	};
	Runnable switchToUsersTurn = new Runnable() {
		
	    public void run() {
	    	if(pokerTable.checkPlayerAllIn(HUMAN_PLAYER))  //if user is all in
	    	{	
	    		Log.d("switchToUsersTurn", "user is all in");
	    		passHand();
	    	}
	    	else if(pokerTable.getNumberOfPlayersInHand() - pokerTable.getNumberOfAllInPlayers() >= 1){  // 
	    		enablePlayerControls();
	    		updateCurrentPlayerIndicator(HUMAN_PLAYER);
	    		Log.d("switchToUsersTurn", "user needs to make a decision");
	    	}
	    	else{   //if dealing out remainder of hand
	    		Log.d("switchToUsersTurn", "pass hand");
	    		passHand();
	    	}
	    	
	    }
	};
	Runnable awardPot = new Runnable() {
	    public void run() {
	    	awardPot();
	    }
	};
	
	public class myRunnable2 implements Runnable{
    	private int playerNum;
    	private int playerChips;
    	private double decision;
    	private int chipAmount;
    	private int potAmount;
    	  public myRunnable2(int curPlayerNum, double dec) {
    	    this.playerNum = curPlayerNum;
    	    this.decision = dec;
    	  }
    	  public myRunnable2(int curPlayerNum,int playersChips, double dec, int chips, int curPot){
    		  this.playerNum = curPlayerNum;
    		  this.decision = dec;
    		  this.chipAmount = chips;
    		  this.potAmount = curPot;
    		  this.playerChips = playersChips;
    	  }
    	  
		public void run() {
			if(pokerTable.checkPlayerAllIn(playerNum)){
	    		Toast.makeText(aGame.this, "Player " + (playerNum+1) + " is ALL IN", Toast.LENGTH_LONG).show();
	    		Log.d("My Runnable2", "    Player " + (playerNum+1) + " is ALL IN");
	    		setPlayerStatusIndicator(playerNum,cBehaviorModule.ALL_IN, chipAmount);
	    	}
	    	else if(decision == cBehaviorModule.CHECK){
	    		Toast.makeText(aGame.this, "Player " + (playerNum+1) + " chose to CHECK", Toast.LENGTH_LONG).show();
	    		Log.d("My Runnable2", "    Player " + (playerNum+1) + " chose to CHECK");
	    		setPlayerStatusIndicator(playerNum,decision,chipAmount);
	    	}
	    	else if(decision == cBehaviorModule.FOLD){
	    		Toast.makeText(aGame.this, "Player " + (playerNum+1) + " chose to FOLD", Toast.LENGTH_LONG).show();
	    		Log.d("My Runnable2", "    Player " + (playerNum+1) + " chose to FOLD");
	    		updateCardImagesOnFold(playerNum);
	    		setPlayerStatusIndicator(playerNum,decision,chipAmount);
	    	}
	    	else if(decision == cBehaviorModule.CALL){
	    		Toast.makeText(aGame.this, "Player " + (playerNum+1) + " chose to CALL", Toast.LENGTH_LONG).show();
	    		Log.d("My Runnable2", "    Player " + (playerNum+1) + " chose to CALL");
	    		setPlayerStatusIndicator(playerNum,decision,chipAmount);
	    	}
	    	else{   //***** this was modified from a general else
	    		Toast.makeText(aGame.this, "Player " + (playerNum+1) + " chose to RAISE to $" + chipAmount, Toast.LENGTH_LONG).show();
	    		Log.d("My Runnable2", "    Player " + (playerNum+1) + " chose to RAISE to $" + chipAmount );
	    		setPlayerStatusIndicator(playerNum,cBehaviorModule.RAISE,chipAmount);
	    	}
	    	playerJustMadeTurn = true;
	    	updateGUI(playerNum, playerChips, potAmount, chipAmount);
	    }
    }
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    public void onResume(){
    	super.onResume();
    	initialize();
    }
    public void onPause(){
    	super.onPause();
    }
    public void onDestroy(){
    	super.onDestroy();
    }
    public void onStop(){
    	super.onStop();
    }
    
    private void initialize(){
    	
    	lytPlayer0 = (AbsoluteLayout)findViewById(R.id.lytP0);
    	lytPlayer1 = (AbsoluteLayout)findViewById(R.id.lytP1);
    	lytPlayer2 = (AbsoluteLayout)findViewById(R.id.lytP2);
    	lytPlayer3 = (AbsoluteLayout)findViewById(R.id.lytP3);
    	
    	initializeGame();
    	initializeText();
    	initializeButtons();
    	initializeCardImages();
    	initializeSlider();
    	initializeDealerButtonGraphics();
    	updateText();
    	
    	
    	//testAwardPot();
    	/*
    	Log.d("Initialize", "Testing buttons");
    	
    	Log.d("Initialize", "Clicking Call");
    	btnCall.performClick();
    	Log.d("Initialize", "Clicking Fold");
    	btnFold.performClick();
    	Log.d("Initialize", "Clicking Check");
    	btnCheck.performClick();
    	Log.d("Initialize", "Clicking Bet");
    	btnBet.performClick();
    	Log.d("Initialize", "Clicking All In");
    	btnAllIn.performClick();
    	*/
    	newHand();
    }
    
    /**  
     * Initializes the slider widget that is used to control player bet amounts 
     */
    private void initializeSlider(){
    	sliderBet = 0;
    	sldrBettingSlider = (SeekBar)findViewById(R.id.aGame_sldrBettingSlider);
    	sldrBettingSlider.setMax(100);
    	listenerBettingSlider = new SeekBar.OnSeekBarChangeListener() {
			public void onStopTrackingTouch(SeekBar seekBar) {}
			public void onStartTrackingTouch(SeekBar seekBar) {}
			
			public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {
				double percent = (double)sldrBettingSlider.getProgress();
				double min = 0;
				double max = pokerTable.getPlayerChipAmount(HUMAN_PLAYER);
				sliderBet = (int)((max-min)*(percent/100));// - pokerTable.getPlayerChipsInRound(HUMAN_PLAYER));
				//updateText();
				updateSliderText();
			}
		};
		sldrBettingSlider.setOnSeekBarChangeListener(listenerBettingSlider);
	}
    
    /* 
     * Initializes the various Button widgets and creates the neccessary OnClickListeners for each button 
     */
    private void initializeButtons(){
    	// Initialize All In Button
    	btnAllIn = (Button)findViewById(R.id.aGame_btnAllIn);
    	listenerAllIn = new Button.OnClickListener(){
    		public void onClick(View v) {
    			Log.d("allInButton", "All In button was clicked");
    			pokerTable.raise(HUMAN_PLAYER, pokerTable.getPlayerChipAmount(HUMAN_PLAYER));
    			setPlayerStatusIndicator(HUMAN_PLAYER,cBehaviorModule.ALL_IN, pokerTable.getPlayerChipAmount(HUMAN_PLAYER));
    			updatePlayerChipText(HUMAN_PLAYER,pokerTable.getPlayerChipAmount(HUMAN_PLAYER), pokerTable.getCurrentPot(),pokerTable.getCurrentBet());
    			passHand();
    		}
        };
        btnAllIn.setOnClickListener(listenerAllIn);
        
    	// Initialize call button
    	btnCall = (Button)findViewById(R.id.aGame_btnCall);
    	listenerCall = new Button.OnClickListener(){
    		public void onClick(View v) {
    			Log.d("callButton", "Call button was clicked");
    			pokerTable.call(HUMAN_PLAYER);
    			setPlayerStatusIndicator(HUMAN_PLAYER,cBehaviorModule.CALL,0);
    			updateText();
    			updatePlayerChipText(HUMAN_PLAYER,pokerTable.getPlayerChipAmount(HUMAN_PLAYER), pokerTable.getCurrentPot(),pokerTable.getCurrentBet());
    			passHand();
    		}
        };
        btnCall.setOnClickListener(listenerCall);
        
        // Initiailize check button
        btnCheck = (Button)findViewById(R.id.aGame_btnCheck);
        listenerCheck = new OnClickListener(){
        	public void onClick(View v) {
        		Log.d("checkButton", "Check button was clicked");
        		pokerTable.check(HUMAN_PLAYER);
        		setPlayerStatusIndicator(HUMAN_PLAYER,cBehaviorModule.CHECK,0);
    			passHand();
    		}
        };
        btnCheck.setOnClickListener(listenerCheck);
        
        //Initialize fold button
        btnFold = (Button)findViewById(R.id.aGame_btnFold);
        listenerFold = new OnClickListener(){
        	public void onClick(View v) {
        		Log.d("foldButton", "Fold button was clicked");
        		pokerTable.fold(HUMAN_PLAYER);
        		updateCardImagesOnFold(HUMAN_PLAYER);
        		setPlayerStatusIndicator(HUMAN_PLAYER,cBehaviorModule.FOLD,0);
    			passHand();
    		}
        };
        btnFold.setOnClickListener(listenerFold);
        
        //Initialize bet button
        btnBet = (Button)findViewById(R.id.aGame_btnBet);
        listenerBet = new OnClickListener(){
        	public void onClick(View v) {
        		Log.d("betButton", "Bet button was clicked");
        		
    			if(sliderBet + pokerTable.getPlayerChipsInRound(HUMAN_PLAYER) > pokerTable.getCurrentBet())  //if the slider amount is greater than the current bet is a raise
    			{	//pokerTable.placeHumanBet(sliderBet);	
    				pokerTable.raise(HUMAN_PLAYER, sliderBet);
    				setPlayerStatusIndicator(HUMAN_PLAYER,cBehaviorModule.RAISE, sliderBet);
        			//updateText();
    				updatePlayerChipText(HUMAN_PLAYER,pokerTable.getPlayerChipAmount(HUMAN_PLAYER), pokerTable.getCurrentPot(),pokerTable.getCurrentBet());
        			passHand();
    			}
    			else if(sliderBet+ pokerTable.getPlayerChipsInRound(HUMAN_PLAYER) == pokerTable.getCurrentBet())  //if the slider amount equals the bet it's a call
    			{		
    				pokerTable.call(HUMAN_PLAYER);
    				setPlayerStatusIndicator(HUMAN_PLAYER,cBehaviorModule.CALL, sliderBet);
        			//updateText();
    				updatePlayerChipText(HUMAN_PLAYER,pokerTable.getPlayerChipAmount(HUMAN_PLAYER), pokerTable.getCurrentPot(),pokerTable.getCurrentBet());
        			passHand();
    			}
        		else{
        			Toast.makeText(aGame.this, "Bet not large enough", Toast.LENGTH_SHORT).show();
        		}
    			
    		}
        	
        };
        btnBet.setOnClickListener(listenerBet);
        
    }
    
    /** 
     * Initializes the poker model
     * 
     * Creates an instance of cTable() to act as the poker model and initializes and game specific values such 
     *  as the minimum bet amount
     */
    private void initializeGame(){
    	
    	pokerTable = new cTable();
    	pokerTable.setMinBet(MIN_BET);
    	
    }
    
    /**
     *  Initializes the TextViews and sets their starting values
     * The TextViews are the current pot, the chip amounts for each player
     *   and labels for the betting slider
     */
    private void initializeText(){
    	txtCurrentPot = (TextView)findViewById(R.id.aGame_textCurrentPot);
    	txtCurrentPot.setText(CURRENTPOT);
    	
    	txtCurrentBet = (TextView)findViewById(R.id.aGame_txtCurrentBet);
    	txtCurrentBet.setText("0");
    	
    	txtCurrentRound = (TextView)findViewById(R.id.aGame_txtCurrenRound);
    	
    	txtPlayer0Status = (TextView)findViewById(R.id.aGame_txtP0Status);
    	txtPlayer1Status = (TextView)findViewById(R.id.aGame_txtP1Status);
    	txtPlayer2Status = (TextView)findViewById(R.id.aGame_txtP2Status);
    	txtPlayer3Status = (TextView)findViewById(R.id.aGame_txtP3Status);
    	
    	
    	txtPlayer0Chips = (TextView)findViewById(R.id.aGame_txtPlayer0Chips);
    	txtPlayer0Chips.setText(CHIPS);
    	txtPlayer1Chips = (TextView)findViewById(R.id.aGame_txtPlayer1Chips);
    	txtPlayer1Chips.setText(CHIPS);
    	txtPlayer2Chips = (TextView)findViewById(R.id.aGame_txtPlayer2Chips);
    	txtPlayer2Chips.setText(CHIPS);
    	txtPlayer3Chips = (TextView)findViewById(R.id.aGame_txtPlayer3Chips);
    	txtPlayer3Chips.setText(CHIPS);
    	
    	txtSliderValue = (TextView)findViewById(R.id.aGame_txtSliderValue);
    	txtSliderValue.setText(CHIPS+pokerTable.getMinBet());
    }
    /* Initializes the ImageViews that represent each players' cards and the community cards
     * The cards are initialized to be invisible
     *    They are made visible when 'dealt' to simulate the dealing action
     */
    private void initializeCardImages(){
    	imgPlayer0Card1 = (ImageView)findViewById(R.id.imgP0C1); imgPlayer0Card1.setVisibility(View.INVISIBLE);
    	imgPlayer0Card2 = (ImageView)findViewById(R.id.imgP0C2); imgPlayer0Card2.setVisibility(View.INVISIBLE);
    	
    	imgPlayer1Card1 = (ImageView)findViewById(R.id.imgP1C1); imgPlayer1Card1.setVisibility(View.INVISIBLE);
    	imgPlayer1Card2 = (ImageView)findViewById(R.id.imgP1C2); imgPlayer1Card2.setVisibility(View.INVISIBLE);
    	
    	imgPlayer2Card1 = (ImageView)findViewById(R.id.imgP2C1); imgPlayer2Card1.setVisibility(View.INVISIBLE);
    	imgPlayer2Card2 = (ImageView)findViewById(R.id.imgP2C2); imgPlayer2Card2.setVisibility(View.INVISIBLE);
    	
    	imgPlayer3Card1 = (ImageView)findViewById(R.id.imgP3C1); imgPlayer3Card1.setVisibility(View.INVISIBLE);
    	imgPlayer3Card2 = (ImageView)findViewById(R.id.imgP3C2); imgPlayer3Card2.setVisibility(View.INVISIBLE);
    	
    	imgCommCard1 = (ImageView)findViewById(R.id.imgComm1); imgCommCard1.setVisibility(View.INVISIBLE);
    	imgCommCard2 = (ImageView)findViewById(R.id.imgComm2); imgCommCard2.setVisibility(View.INVISIBLE);
    	imgCommCard3 = (ImageView)findViewById(R.id.imgComm3); imgCommCard3.setVisibility(View.INVISIBLE);
    	imgCommCard4 = (ImageView)findViewById(R.id.imgComm4); imgCommCard4.setVisibility(View.INVISIBLE);
    	imgCommCard5 = (ImageView)findViewById(R.id.imgComm5); imgCommCard5.setVisibility(View.INVISIBLE);
    	
    }
    /*
     * Initializes the ImageView for the dealer button
     * Creates a list of cPoint objects to store the coordinates of each dealer button position (1 for each player)
     * The initial position of the button image is set by getting the position of the dealer button from the 
     *   cTable object pokerTable.  That player index is used to get the correct cPoint object from the list
     *   and then positions the image using the stored coordinates
     */
    private void initializeDealerButtonGraphics(){
    	gameLayout = (AbsoluteLayout) findViewById(R.id.aGame_Layout);
    	imgDealerButton = new ImageView(this);
    	imgDealerButton.setImageDrawable(getResources().getDrawable(android.R.drawable.presence_invisible));
    	
    	AbsoluteLayout.LayoutParams layoutParams = new AbsoluteLayout.LayoutParams(dealerButtonWidth, dealerButtonHeight, 0, 0);
    	imgDealerButton.setLayoutParams(layoutParams);
    	gameLayout.addView(imgDealerButton);
    	
    	dealerButtonPoints = new ArrayList<cPoint>();
    	cPoint point2 = new cPoint(400-dealerButtonWidth/2,145);
    	cPoint point0 = new cPoint(400-dealerButtonWidth/2,220);
    	cPoint point1 = new cPoint(75,150);
    	cPoint point3 = new cPoint(725,150);
    	
    	dealerButtonPoints.add(point0);
    	dealerButtonPoints.add(point1);
    	dealerButtonPoints.add(point2);
    	dealerButtonPoints.add(point3);
    	
    	imgDealerButton.setX(dealerButtonPoints.get(pokerTable.getDealerButton()).getX());
    	imgDealerButton.setY(dealerButtonPoints.get(pokerTable.getDealerButton()).getY());
    	imgDealerButton.invalidate();
    }

/**********************************************************************************************/  
       
    /**
     * Passes the betting to the next round
     * 
     * It gets the current betting round number from pokerTable (cTable object) and calls the appropriate betting function
     * 		This serves to restart the game flow after it is suspended to turn control back to the human player
     */
    private void passHand(){
    	//Log.d("passHand", "   Hand just passed from the user");
    	userJustMadeTurn = true;
    	playerJustMadeTurn = true;
    	disablePlayerControls();
    	updateSlider();
    	roundOfBetting();
    }
    
    /*
     * newHand() is called at the start of a new game, or at the end of awardPot() if they game is not over
     *   It disables the users controls to start the round
     *   it initializes the poker model to start a new hand
     *   clears the current player indicator
     *   calls the preFlop() method
     */
    private void newHand(){
    	disablePlayerControls();       //disable user controls
    	playerJustMadeTurn = true;
    	pokerTable.handInitialization();    //initializes a new hand in the poker model. (removes player cards, set players as active in hand)
    	//clearCurrentPlayerIndicator();    //removes the red square around the current player since there is no current player at this point
    	preFlop();    //pass along the game flow
    }
    
    /**
     * Handles the updating of the dealer button
     * 
     * It first calls moveDealerButton() in the cTable class to update the poker model
     * Then, it updates the GUI to match the new dealer button state
     * 
     */
    private void moveDealerButton(){
    	pokerTable.moveDealerButton();
    	
    	resetAllPlayerStatusIndicators();  //updates the label of the status of the player in the current hand
    	updateSmallBlindPlayerStatus(pokerTable.getSmallBlindIndex());
    	updateLargeBlindPlayerStatus(pokerTable.getLargeBlindIndex());
    	
    	int start = pokerTable.getDealerButton()+3;
    	int firstToAct = -1;
    	for(int i = start; i < (start+4)%4; i++){
    		if(pokerTable.checkPlayerInGame(i) && pokerTable.checkPlayerInHand(i))
    		{	firstToAct = i;
    			break;
    		}
    	}
    	updateCurrentPlayerIndicator(firstToAct);  //updates the current player indicator
    	
    	imgDealerButton.setX(dealerButtonPoints.get(pokerTable.getDealerButton()).getX());
    	imgDealerButton.setY(dealerButtonPoints.get(pokerTable.getDealerButton()).getY());
    	
    	Log.d("aGame.moveDealerButton", "Button on Player "+(pokerTable.getDealerButton()+1));
    	imgDealerButton.invalidate();
    	
    	updateText();
   }
    
    /*
     * called from newHand()
     * moves the dealer button to the next active player
     * updates the current Player indicator to be one the player to the left of the dealer button
     * deals a new hand
     */
    private void preFlop(){
    	//resetAllPlayerStatusIndicators();  //updates the label of the status of the player in the current hand  //moved to moveDealerButton()
    	moveDealerButton();
    	//updateCurrentPlayerIndicator((pokerTable.getDealerButton() + 3) % 4);  //moved to moveDealerButton()
    	dealHand();
    }
    
    private void dealHand(){
    	int order = 0;
    	//for(int i = pokerTable.getDealerButton();i < pokerTable.getDealerButton()+pokerTable.getNumberOfActivePlayers();i++)
    	for(int i = pokerTable.getDealerButton();i < pokerTable.getDealerButton()+4;i++)
    	{	
    		int timeOffset2 = order*500;
    		if(timeOffset2 == 0){
    			timeOffset2 = pokerTable.getNumberOfActivePlayers() * 500;
    		}
    		else{
    			timeOffset2 = pokerTable.getNumberOfActivePlayers() * 500 + order*500;
    		}
    		int currentCardsToUpdate = i;  //+1
    		int playerNum = currentCardsToUpdate % 4;
    			if(playerNum == 0 && pokerTable.checkPlayerInGame(playerNum) ){
    				mHandler.postDelayed(dealPlayer0Card1, (order*500));
    				mHandler.postDelayed(dealPlayer0Card2,  timeOffset2);
    				order++;
    			}
    			else if(playerNum == 1 && pokerTable.checkPlayerInGame(playerNum) ){
    				mHandler.postDelayed(dealPlayer1Card1, (order*500));
    				mHandler.postDelayed(dealPlayer1Card2, timeOffset2);
    				order++;
    			}
    			else if(playerNum == 2 && pokerTable.checkPlayerInGame(playerNum) ){
    				mHandler.postDelayed(dealPlayer2Card1, (order*500));
    				mHandler.postDelayed(dealPlayer2Card2,  timeOffset2);
    				order++;
    			}
    			else if(playerNum == 3 && pokerTable.checkPlayerInGame(playerNum) ){
    				mHandler.postDelayed(dealPlayer3Card1, (order*500));
    				mHandler.postDelayed(dealPlayer3Card2,  timeOffset2);
    				order++;
    			}
    		
    	}
    	mHandler.postDelayed(moveToBettingAfterDeal, TIME_AFTER_BETTING_ROUND);
    }
    
   
    private void flop(){
    	refundChips();
    	pokerTable.incrementBettingRound();
    	clearCurrentPlayerIndicator();
    	resetAllPlayerStatusIndicators();
    	updateText();
    	
    	Log.d("flop", "The Flop just happend");
    	Toast.makeText(this, "Round " + pokerTable.getCurrentRoundNumber() + " Flop", Toast.LENGTH_LONG).show();
    	
    	userJustMadeTurn = false;
    	pokerTable.flop();
    	
    	mHandler.postDelayed(dealFlop1, 750);
    	mHandler.postDelayed(dealFlop2, 1500);
    	mHandler.postDelayed(dealFlop3, 2250);
    	//mHandler.postDelayed(moveToBettingFromFlop, 2500);
    	mHandler.postDelayed(moveToBettingAfterRound, 2500);
    	
    }
    private void turn(){
    	refundChips();
    	pokerTable.incrementBettingRound();
    	clearCurrentPlayerIndicator();
    	resetAllPlayerStatusIndicators();
    	updateText();
    	Log.d("turn", "The Turn just happend");
    	Toast.makeText(this, "Round " + pokerTable.getCurrentRoundNumber() + " Turn", Toast.LENGTH_LONG).show();
    	
    	userJustMadeTurn = false;
    	pokerTable.turn();
    	
    	mHandler.postDelayed(dealTurn1, 750);
    	mHandler.postDelayed(moveToBettingAfterRound, 1500);
    }
    private void river(){
    	refundChips();
    	pokerTable.incrementBettingRound();
    	clearCurrentPlayerIndicator();
    	resetAllPlayerStatusIndicators();
    	updateText();
    	Log.d("turn", "The River just happend");
    	Toast.makeText(this, "Round " + pokerTable.getCurrentRoundNumber() + " River", Toast.LENGTH_LONG).show();
    	
    	userJustMadeTurn = false;
    	pokerTable.river();
    	
    	mHandler.postDelayed(dealRiver1, 750);
    	mHandler.postDelayed(moveToBettingAfterRound, 1500);
    }
 
    /** refundChips()
     * 
     * Determines, at the end of a round, if a player has too many chips in the hand and gives a refund.
     * 
     * This method is designed to fix the issues of a player forcing another player all-in.  
     * If player x bets 500 but player y only has 300 player x should get 200 back.
     * 
     */
    
    private void refundChips(){
    	int maxBet = 0;
    	int secondMaxBet = 0;
    	for(int i = 0; i < 4; i++){
    		if(pokerTable.checkPlayerInGame(i) && pokerTable.checkPlayerInHand(i)){
    			int curPlayerChips = pokerTable.getPlayerChipsInRound(i);
    			if(curPlayerChips >= maxBet){
    				secondMaxBet = maxBet;
    				maxBet = curPlayerChips;
    			}
    			else if(curPlayerChips < maxBet && curPlayerChips > secondMaxBet){
    				secondMaxBet = curPlayerChips;
    			}
    		}
    	}
    	
    	Log.d("aGame.refundChips", "maxBet: " + maxBet);
    	Log.d("aGame.refundChips", "secondMaxBet: " + secondMaxBet);
    	
    	for(int i = 0; i < 4; i++){
    		if(pokerTable.checkPlayerInHand(i) && pokerTable.checkPlayerInGame(i)){
	    		if(pokerTable.getPlayerChipsInRound(i) > secondMaxBet && pokerTable.getPlayerChipsInRound(i) <= maxBet){
	    			int refund = pokerTable.getPlayerChipsInRound(i) - secondMaxBet;
	    			System.out.println( "Player " +(i+i) + " getting refund of " + refund);
	    			pokerTable.refundChips(i, refund);
	    			
	    		}
    		}
    	}
    	
    }
    
    /**
     * 
     */
    private void roundOfBetting(){
    	//Log.d("aGame.roundOfBetting", "Logic for player decision making.  Players left to act: " + pokerTable.getNumberOfPlayersToAct());
    	//Log.d("aGame.roundOfBetting", "      Players in hand: " + pokerTable.getNumberOfPlayersInHand());
    	//Log.d("aGame.roundOfBetting", "      Players left to act: " + pokerTable.getNumberOfAllInPlayers());
    	
    	boolean usersTurn = false;
    	int decisionsMade = 0;  //used for timing
    	int counter = 0;  //the counter used to calculate the player index as play passes around
    	
    	// determine where to start betting
    	if(userJustMadeTurn)
    	{	counter = 1;	}
    	else if(pokerTable.getBettingRound() == 1)
    	{	counter = pokerTable.getLargeBlindIndex()+1;}  //start the player index counter at the player to the left of the big blind
    	else
    	{	counter = pokerTable.getSmallBlindIndex();	} //try setting this to +1 if problems arise
    	
    	// start the loop which will handle betting 
    	while(pokerTable.getNumberOfPlayersToAct() > 0){
    		//check if it's the user's turn.  If it is, the while loop breaks so the user can make a decision
			int playerToAct = counter % 4;
			if(playerToAct == 0 && pokerTable.checkPlayerInHand(HUMAN_PLAYER)){
				usersTurn = true;
				//Log.d("aGame.roundOfBetting", "goo");
				break;
			}
			//if the player is currently in the game and not all in
			if(pokerTable.checkPlayerInGame(playerToAct) && pokerTable.checkPlayerInHand(playerToAct) && !pokerTable.checkPlayerAllIn(playerToAct)){
				if(pokerTable.getNumberOfPlayersInHand() == 1)
				{	
					Log.d("aGame.roundOfBetting", "broke out because only 1 left");
					break;									
				
				}
				final int playerNum = playerToAct;
				//Log.d("aGame.roundOfBetting", "Player "+(playerNum+1) + " making decision");
				decisionsMade++;
				double decision = pokerTable.getPlayerDecision(playerNum);
				Log.d("aGame.roundOfBetting", "Player "+(playerNum+1) + " chooses " + decision);
				myRunnable2 playerDecision;
				playerDecision = new myRunnable2(playerNum, pokerTable.getPlayerChipAmount(playerNum), decision,pokerTable.getCurrentBet(), pokerTable.getCurrentPot());
				mHandler.postDelayed(playerDecision, decisionsMade * TIME_DELAY);
				if(userJustMadeTurn){userJustMadeTurn = false;}
			}
			counter++;
		}
		
    	if(pokerTable.getNumberOfPlayersInHand() == 1 ){      //after break, if there is only 1 player left in the hand award the pot
    		mHandler.postDelayed(awardPot, (decisionsMade+1)*TIME_DELAY);
    		Log.d("aGame.roundOfBetting", "soo");
    	}  
    	else if(usersTurn == true){							//after break, if it's the users turn switch control to the user
    		mHandler.postDelayed(switchToUsersTurn, (decisionsMade+1)*TIME_DELAY);
    		Log.d("aGame.roundOfBetting", "aoo");
    	}
    	else{
    		if(pokerTable.getBettingRound() == 1)
    			mHandler.postDelayed(dealFlop, (decisionsMade+1)*TIME_AFTER_BETTING_ROUND);	
    		else if(pokerTable.getBettingRound() == 2)
    			mHandler.postDelayed(dealTurn, (decisionsMade+1)*TIME_AFTER_BETTING_ROUND);
    		else if(pokerTable.getBettingRound() == 3)
    			mHandler.postDelayed(dealRiver, (decisionsMade+1)*TIME_AFTER_BETTING_ROUND);
    		else if(pokerTable.getBettingRound() == 4)
    			mHandler.postDelayed(awardPot, (decisionsMade+1)*TIME_AFTER_BETTING_ROUND);
    	}
    	
    	
    }
   
    /** awardPot()
     * 
     * Called at the end of a hand whether because all but one player has folded or because the rounds of betting
     *   are finished   
     * 
     */
    private void awardPot(){
    	Log.d("aGame.awardPot", "awardPot() is started");
    	//refundChips();
    	clearCurrentPlayerIndicator();   //clears the red square from the last active player
    	
    	// for each player left in the hand, show their cards so it can be seen what their hand was
    	for(int i = 0; i < 4; i++){
    		if(pokerTable.checkPlayerInHand(i) == true && pokerTable.checkPlayerInGame(i) == true){
    			Log.d("aGame.awardPot", "   award pot thinks player " + i + " is in the hand");
    			updateCardImagesOnHandEnd(i);
    		}
    	}
    	
    	// build a string to use in the toast message.  The string will indicate which player(s) won the hand
    	String winMsg = "Hand " + pokerTable.getCurrentRoundNumber() + ": Awarding Pot to Player(s) ";
    	ArrayList<cRank> winners = pokerTable.awardPot();
    	for(int i =0; i < winners.size(); i++){
    		int guiIndex = winners.get(i).playerIndex + 1;
    		winMsg+= guiIndex + " ";
    	}
    	int rank = winners.get(0).handRank;
    	if(rank < 9){
    		rank *= HandEvaluator.ID_GROUP_SIZE;
    		Log.d("awardPot", "convertedID");
    	}
    	Log.d("awardPot", "handRank: " + rank);
    	
    	winMsg += "  They win with " + HandEvaluator.name_hand(rank);
    	Toast.makeText(this, winMsg , Toast.LENGTH_LONG).show();  //Show the toast message indicating who won
    	
    	mHandler.postDelayed(updateGUIEndOfHand, 5000);  //update the gui for hand's end
    	mHandler.postDelayed(endOfHand, 6000);  //call the endOfHand runnable which handles end game logic
    	
    	Log.d("awardPot", "awardPot() has ended");
    }
    
/** GUI Methods *******************************************************************************************/  
    
    /**
     * Updates the GUI after each players' turn
     * 
     * After a player makes their turn, the GUI needs updated.
     * This is to provide feedback to user about what has happened
     *   including:  Was a bet was made?; How large a bet was made?;
     *   Did a player fold?;  Whose turn it is?
     * 
     * @param playerNum
     */
    private void updateGUI(int playerNum, int playerChipAmount, int curPot, int curBet ){
    	updateCurrentPlayerIndicator(playerNum);
    	updatePlayerChipText(playerNum, playerChipAmount, curPot, curBet);
    }
    
    /**
     * Disables the "Check" button when a bet has been made
     */
    private void disableCheckButton(){
    	btnCheck.setEnabled(false);
    }
    
    /**
     * Disables the "Call" button when the current bet is greater than the player's chips
     */
    private void disableCallButton(){
    	btnCall.setEnabled(false);
    }
    
    /**
     * Disables the "Bet" button when the current bet is larger than the player's chips
     */
    private void disableBetButton(){
    	btnBet.setEnabled(false);
    }
    
    /**
     * Updates the slider after a bet is made so the minimum bet amount is now the current bet
     */
    
    private void updateSlider(){
    	//sliderBet = pokerTable.getCurrentBet();
    	sldrBettingSlider.setMax(100);
    	sldrBettingSlider.setProgress(0);
    	listenerBettingSlider = new SeekBar.OnSeekBarChangeListener() {
			
			public void onStopTrackingTouch(SeekBar seekBar) {}
			public void onStartTrackingTouch(SeekBar seekBar) {}
			
			public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {
				double percent = (double)sldrBettingSlider.getProgress();
				
				//double min = pokerTable.getCurrentBet();
				 double min = 0;
				double max = pokerTable.getPlayerChipAmount(HUMAN_PLAYER);
				
				sliderBet = (int)((max-min)*(percent/100));// - pokerTable.getPlayerChipsInRound(HUMAN_PLAYER));
				//updateText();
				updateSliderText();
			}
		};
		sldrBettingSlider.setOnSeekBarChangeListener(listenerBettingSlider);
    }
    
    /** updateText()
     * 
     * Updates the text for the current pot, current bet, chip amounts for each player, and the slider label for the player
     * 
     * Called from initialize(), flop(), turn(), river(), moveDealerButton(), updateGUIEndOfHand
     */
    private void updateText(){
    	txtCurrentPot.setText(CURRENTPOT+pokerTable.getCurrentPot());
    	txtCurrentBet.setText(CURRENTBET+pokerTable.getCurrentBet());
    	
    	txtCurrentRound.setText(CURRENTROUND+pokerTable.getCurrentRoundNumber());
    	
    	txtPlayer0Chips.setText(CHIPS+pokerTable.getPlayerChipAmount(HUMAN_PLAYER));
    	
    	txtPlayer1Chips.setText(CHIPS+pokerTable.getPlayerChipAmount(1));
    	
    	txtPlayer2Chips.setText(CHIPS+pokerTable.getPlayerChipAmount(2));
    	
    	txtPlayer3Chips.setText(CHIPS+pokerTable.getPlayerChipAmount(3));
    	
    	txtSliderValue.setText(CHIPS+sliderBet);
    }
    
    private void updateSliderText(){
    	txtSliderValue.setText(CHIPS+sliderBet);
    }
    
    /** updatePlayerChipText(int playerNum)
     * 
     * Updates the text representing the specified player's chip total.
     * 
     * Called from updateGUI(), listenerBet, listenerCall
     * 
     * @param playerNum The integer index of the specified player.  Range 0-3.
     */
    private void updatePlayerChipText(int playerNum,int playerChipAmount, int curPot, int curBet){
    	txtCurrentPot.setText(CURRENTPOT+curPot);
    	txtCurrentBet.setText(CURRENTBET+curBet);
    	
    	if(playerNum == HUMAN_PLAYER)
    	{		
    		txtPlayer0Chips.setText(CHIPS+playerChipAmount);
    		txtSliderValue.setText(CHIPS+sliderBet);
    	}
    	else if(playerNum == 1)
    		txtPlayer1Chips.setText(CHIPS+playerChipAmount);
    	else if(playerNum == 2)
    		txtPlayer2Chips.setText(CHIPS+playerChipAmount);
    	else if(playerNum == 3)
    		txtPlayer3Chips.setText(CHIPS+playerChipAmount);
    }
  
    /** resetAllPlayerStatusIndicators()
     * 
     * Sets the status indicator of each player to an initial value.  
     * 
     * The value is either "OUT OF GAME" if they've lost, "OUT OF HAND" if they've folded
     *   or "YET TO ACT" if they are in the game but haven't made their turn yet.
     * 
     * Called from moveToBettingAfterDeal, moveToBettingAfterRound, moveDealerButton()
     */
    
    private void resetAllPlayerStatusIndicators(){
    	int tmp[] = new int[4];
    	for(int i = 0; i < 4; i ++){
    		tmp[i] = 1;
    	}
    	tmp[pokerTable.getSmallBlindIndex()] = 0;
    	tmp[pokerTable.getLargeBlindIndex()] = 0;
    	
    	for(int i = 0; i < 4; i ++){
    		//if(tmp[i] == 1)
    			//if(pokerTable.checkPlayerInGame(i))
    				resetPlayerStatusIndicator(i);
    	}
    	
    }
    
    
    private void updateSmallBlindPlayerStatus(int playerNum){
    	String label = "SMALL BLIND: $"+pokerTable.getPlayerChipsInRound(playerNum);
    	if(playerNum == HUMAN_PLAYER){
    		txtPlayer0Status.setText(label);
    		txtPlayer0Status.invalidate();
    	}
    	else if(playerNum == 1){
    		txtPlayer1Status.setText(label);
    		txtPlayer1Status.invalidate();
    	}
    	else if (playerNum == 2){
    		txtPlayer2Status.setText(label);
    		txtPlayer2Status.invalidate();
    	}
    	else if(playerNum == 3){
    		txtPlayer3Status.setText(label);
    		txtPlayer3Status.invalidate();
    	}
    }
    private void updateLargeBlindPlayerStatus(int playerNum){
    	String label = "LARGE BLIND: $"+pokerTable.getPlayerChipsInRound(playerNum);
    	if(playerNum == HUMAN_PLAYER){
    		txtPlayer0Status.setText(label);
    		txtPlayer0Status.invalidate();
    	}
    	else if(playerNum == 1){
    		txtPlayer1Status.setText(label);
    		txtPlayer1Status.invalidate();
    	}
    	else if (playerNum == 2){
    		txtPlayer2Status.setText(label);
    		txtPlayer2Status.invalidate();
    	}
    	else if(playerNum == 3){
    		txtPlayer3Status.setText(label);
    		txtPlayer3Status.invalidate();
    	}
    }
    /**
     * Sets the status indicator of a specified player
     * 
     * Called from a runnable before each round and in resetAllPlayerStatusIndicators()
     * 
     * @param playerNum The index of the specified player.
     */
  
    private void resetPlayerStatusIndicator(int playerNum){
    	if(playerNum == 0 ){
    		if(pokerTable.checkPlayerInGame(playerNum))
    			if(!pokerTable.checkPlayerInHand(playerNum))	
    				txtPlayer0Status.setText("OUT OF HAND");
    			else
    				txtPlayer0Status.setText("YET TO ACT");
    		else
    			txtPlayer0Status.setText("OUT OF GAME");
    		
        	txtPlayer0Status.setVisibility(View.VISIBLE);
        	txtPlayer0Status.invalidate();
    	}
    	else if(playerNum == 1){
    		if(pokerTable.checkPlayerInGame(playerNum))
    			if(!pokerTable.checkPlayerInHand(playerNum))
    				txtPlayer1Status.setText("OUT OF HAND");
    			else
    				txtPlayer1Status.setText("YET TO ACT");
    		else
    			txtPlayer1Status.setText("OUT OF GAME");
    		
        	txtPlayer1Status.setVisibility(View.VISIBLE);
        	txtPlayer1Status.invalidate();
    	}
    	else if (playerNum == 2){
    		if(pokerTable.checkPlayerInGame(playerNum))
    			if(!pokerTable.checkPlayerInHand(playerNum))
    				txtPlayer2Status.setText("OUT OF HAND");
    			else
    				txtPlayer2Status.setText("YET TO ACT");
    		else
    			txtPlayer2Status.setText("OUT OF GAME");
    		
        	txtPlayer2Status.setVisibility(View.VISIBLE);
        	txtPlayer2Status.invalidate();
    	}
    	else if(playerNum == 3){
    		if(pokerTable.checkPlayerInGame(playerNum))
    			if(!pokerTable.checkPlayerInHand(playerNum))
    				txtPlayer3Status.setText("OUT OF HAND");
    			else
    				txtPlayer3Status.setText("YET TO ACT");
    		else
    			txtPlayer3Status.setText("OUT OF GAME");
    		
        	txtPlayer3Status.setVisibility(View.VISIBLE);
        	txtPlayer3Status.invalidate();
    	}
    }
  
    private void setPlayerStatusIndicator(int playerNum, double playerChoice, int chipAmount){
    	if(playerNum == 0){
    		if(playerChoice == cBehaviorModule.FOLD){
    			txtPlayer0Status.setText("FOLD");
    		}
    		else if(playerChoice == cBehaviorModule.CHECK){
    			txtPlayer0Status.setText("CHECK");
    		}
    		else if(playerChoice == cBehaviorModule.CALL){
    			txtPlayer0Status.setText("CALL");
    		}
    		else if(playerChoice == cBehaviorModule.ALL_IN){
    			txtPlayer0Status.setText("ALL IN");
    		}
    		else{
    			txtPlayer0Status.setText("RAISE to " + chipAmount);
    		}
    		txtPlayer0Status.invalidate();
    		
    	}
    	else if (playerNum == 1){
    		if(playerChoice == cBehaviorModule.FOLD){
    			txtPlayer1Status.setText("FOLD");
    		}
    		else if(playerChoice == cBehaviorModule.CHECK){
    			txtPlayer1Status.setText("CHECK");
    		}
    		else if(playerChoice == cBehaviorModule.CALL){
    			txtPlayer1Status.setText("CALL");
    		}
    		else if(playerChoice == cBehaviorModule.ALL_IN){
    			txtPlayer1Status.setText("ALL IN");
    		}
    		else{
    			txtPlayer1Status.setText("RAISE to " + chipAmount);
    		}
    		txtPlayer1Status.invalidate();
    	}
    	else if (playerNum == 2){
    		if(playerChoice == cBehaviorModule.FOLD){
    			txtPlayer2Status.setText("FOLD");
    		}
    		else if(playerChoice == cBehaviorModule.CHECK){
    			txtPlayer2Status.setText("CHECK");
    		}
    		else if(playerChoice == cBehaviorModule.CALL){
    			txtPlayer2Status.setText("CALL");
    		}
    		else if(playerChoice == cBehaviorModule.ALL_IN){
    			txtPlayer2Status.setText("ALL IN");
    		}
    		else{
    			txtPlayer2Status.setText("RAISE to " + chipAmount);
    		}
    		txtPlayer2Status.invalidate();
    	}
    	else if (playerNum == 3){
    		if(playerChoice == cBehaviorModule.FOLD){
    			txtPlayer3Status.setText("FOLD");
    		}
    		else if(playerChoice == cBehaviorModule.CHECK){
    			txtPlayer3Status.setText("CHECK");
    		}
    		else if(playerChoice == cBehaviorModule.CALL){
    			txtPlayer3Status.setText("CALL");
    		}
    		else if(playerChoice == cBehaviorModule.ALL_IN){
    			txtPlayer3Status.setText("ALL IN");
    		}
    		else{
    			txtPlayer3Status.setText("RAISE to " + chipAmount);
    		}
    		txtPlayer3Status.invalidate();
    	}
    }
    
    /** clearPlayerCardImages()
     * 
     * Called at the end of a hand when the GUI is being updated to start the next hand
     */
    private void clearPlayerCardImages(){
    	
    	imgPlayer0Card1.setVisibility(View.INVISIBLE);
    	imgPlayer0Card2.setVisibility(View.INVISIBLE);
    	
    	imgPlayer1Card1.setVisibility(View.INVISIBLE);
    	imgPlayer1Card2.setVisibility(View.INVISIBLE);
    	txtPlayer1Status.setText("");
    	
    	imgPlayer2Card1.setVisibility(View.INVISIBLE);
    	imgPlayer2Card2.setVisibility(View.INVISIBLE);
    	txtPlayer2Status.setText("");
    	
    	imgPlayer3Card1.setVisibility(View.INVISIBLE);
    	imgPlayer3Card2.setVisibility(View.INVISIBLE);
    	txtPlayer3Status.setText("");
    }
    /** updateCardImagesOnFold(int playerNum)
     * 
     * Clears a player's card images when they fold.
     * 
     * When a player chooses to fold, their cards get rid of their cards.  To represent this, we
     *   make the cards invisible on the screen.  This is called from myRunnable2 after a fold
     *   decision has been made by a plaer.
     *   
     * @param playerNum The integer index for the specified player.  Range 0-3.    
     */
    private void updateCardImagesOnFold(int playerNum){
    	if(playerNum == 0){
    		imgPlayer0Card1.setVisibility(View.INVISIBLE);
    		imgPlayer0Card2.setVisibility(View.INVISIBLE);
    	}
    	else if(playerNum == 1){
    		imgPlayer1Card1.setVisibility(View.INVISIBLE);
    		imgPlayer1Card2.setVisibility(View.INVISIBLE);
    	}
    	else if (playerNum == 2){
    		imgPlayer2Card1.setVisibility(View.INVISIBLE);
    		imgPlayer2Card2.setVisibility(View.INVISIBLE);
    	}
    	else if(playerNum == 3){
    		imgPlayer3Card1.setVisibility(View.INVISIBLE);
    		imgPlayer3Card2.setVisibility(View.INVISIBLE);
    	}
    }
    private void updateCardImagesOnHandEnd(int playerNum){
    	if(playerNum == 0 && pokerTable.checkPlayerInHand(playerNum)  ){//&& pokerTable.checkPlayerInGame(playerNum)
    		
    		imgPlayer0Card1.setImageDrawable(getCardImage(pokerTable.getPlayerCardIndex(0, 0)));
    		imgPlayer0Card2.setImageDrawable(getCardImage(pokerTable.getPlayerCardIndex(0, 1)));
    		imgPlayer0Card1.setVisibility(View.VISIBLE);
    		imgPlayer0Card2.setVisibility(View.VISIBLE);
    		imgPlayer0Card1.invalidate();
	    	imgPlayer0Card2.invalidate();
    		
    		
    	}
    	else if(playerNum == 1 && pokerTable.checkPlayerInHand(playerNum)){
    		Log.d("updateCardImagesOnHandEnd", "updating player 2's cards");
    		imgPlayer1Card1.setImageDrawable(getCardImage(pokerTable.getPlayerCardIndex(1, 0)));
    		imgPlayer1Card2.setImageDrawable(getCardImage(pokerTable.getPlayerCardIndex(1, 1)));
    		imgPlayer1Card1.setVisibility(View.VISIBLE);
    		imgPlayer1Card2.setVisibility(View.VISIBLE);
    		imgPlayer1Card1.invalidate();
	    	imgPlayer1Card2.invalidate();
    	}
    	else if (playerNum == 2 && pokerTable.checkPlayerInHand(playerNum)){
    		Log.d("updateCardImagesOnHandEnd", "updating player 3's cards");
    		imgPlayer2Card1.setImageDrawable(getCardImage(pokerTable.getPlayerCardIndex(2, 0)));
    		imgPlayer2Card2.setImageDrawable(getCardImage(pokerTable.getPlayerCardIndex(2, 1)));
    		imgPlayer2Card1.setVisibility(View.VISIBLE);
    		imgPlayer2Card2.setVisibility(View.VISIBLE);
    		imgPlayer2Card1.invalidate();
	    	imgPlayer2Card2.invalidate();
    	}
    	else if(playerNum == 3 && pokerTable.checkPlayerInHand(playerNum)){
    		Log.d("updateCardImagesOnHandEnd", "updating player 4's cards");
    		imgPlayer3Card1.setImageDrawable(getCardImage(pokerTable.getPlayerCardIndex(3, 0)));
    		imgPlayer3Card2.setImageDrawable(getCardImage(pokerTable.getPlayerCardIndex(3, 1)));
    		imgPlayer3Card1.setVisibility(View.VISIBLE);
    		imgPlayer3Card2.setVisibility(View.VISIBLE);
    		imgPlayer3Card1.invalidate();
	    	imgPlayer3Card2.invalidate();
    	}
    }
    
    private void clearCommunityCardImages(){
    	imgCommCard1.setVisibility(View.INVISIBLE);
    	imgCommCard2.setVisibility(View.INVISIBLE);
    	imgCommCard3.setVisibility(View.INVISIBLE);
    	imgCommCard4.setVisibility(View.INVISIBLE);
    	imgCommCard5.setVisibility(View.INVISIBLE);
    }
    private void enablePlayerControls(){
    	btnCall.setEnabled(true);
    	btnCheck.setEnabled(true);
    	btnFold.setEnabled(true);
    	btnBet.setEnabled(true);
    	btnAllIn.setEnabled(true);
    	sldrBettingSlider.setEnabled(true);
    	
    	int currentBet = pokerTable.getCurrentBet();
    	if(currentBet > 0 && pokerTable.getPlayerChipsInRound(HUMAN_PLAYER) < currentBet){
    		disableCheckButton();
    	}
    	if(currentBet == pokerTable.getPlayerChipsInRound(HUMAN_PLAYER))
    		disableCallButton();
    	if(currentBet > pokerTable.getPlayerChipAmount(HUMAN_PLAYER)){
    		disableCallButton();
    		disableBetButton();
    	}
    	if(currentBet == 0){
    		disableCallButton();
    	}
    }
    private void disablePlayerControls(){
    	btnCall.setEnabled(false);
    	btnCheck.setEnabled(false);
    	btnFold.setEnabled(false);
    	btnBet.setEnabled(false);
    	btnAllIn.setEnabled(false);
    	sldrBettingSlider.setEnabled(false);
    }
    
    private void updateCurrentPlayerIndicator(int playerNum){
    	clearCurrentPlayerIndicator();
    	if (playerNum == 0){
    		lytPlayer0.setBackgroundColor(getResources().getColor(android.R.color.tertiary_text_dark));
    	}
    	else if(playerNum == 1){
    		lytPlayer1.setBackgroundColor(getResources().getColor(android.R.color.tertiary_text_dark));
    	}
    	else if (playerNum == 2){
    		lytPlayer2.setBackgroundColor(getResources().getColor(android.R.color.tertiary_text_dark));
    	}
    	else if (playerNum == 3){
    		lytPlayer3.setBackgroundColor(getResources().getColor(android.R.color.tertiary_text_dark));
    	}
    }
    
    private void clearCurrentPlayerIndicator(){
    	lytPlayer0.setBackgroundColor(getResources().getColor(android.R.color.black));
    	lytPlayer1.setBackgroundColor(getResources().getColor(R.color.customGreen));
    	lytPlayer2.setBackgroundColor(getResources().getColor(R.color.customGreen));
    	lytPlayer3.setBackgroundColor(getResources().getColor(R.color.customGreen));
    }
    
    private Drawable getCardImage(int cardIndex){
    	Drawable cardImage = null;
    	cardImage = getResources().getDrawable(getResources().getIdentifier("card"+cardIndex, "drawable", getPackageName()));
    	return cardImage;
    }
}
